<?php
namespace app\api\model;


use app\model\common\UserOauth as UserOauthModel;
use think\facade\Db;

use app\model\common\Web;

use app\model\Base;
use think\facade\Log;
use think\helper\Str;


class User extends Base
{
    public static $direct_rate = [
        'odd'=>0.3,
        'even'=>0.7,
    ];//直推奖比例

    public static $indirect_rate = 0.1;//间推奖比例

    public static $merchant_direct_rate = 0.3;//商家直推奖比例
    public static $merchant_indirect_rate = 0.1;//商家间推奖比例

    public static $team_rate = 0.2;//团队奖比例

    public static $merchant_one_member_amount = 5000;//用户选择收货地址的门店 奖励50

    public static function staticLevelUp($user_id, $parent_ids, $goods_num)
    {
        //静态升级
        //会员：进货1盒
        //县代：一次性进货5盒(或累计进货10盒）
        //市代：累计进货100盒+小店铺进货20盒
        //省代：累计进货1200盒+小店铺进货200盒
        //合伙人：累计进货3200盒+小店铺进货1000盒
        $user_info = self::where('id', $user_id)->find();
        $level_id = $user_info['level_id'];
        $after_goods_num = $user_info['spending'] + $goods_num;
        if($after_goods_num >= 3200)
        {
            $level_id = 5;
        }elseif ($after_goods_num >= 1200)
        {
            $level_id = 4;
        }elseif ($after_goods_num >= 100)
        {
            $level_id = 3;
        }elseif ($after_goods_num >= 10)
        {
            $level_id = 2;
        }else{
            if($goods_num > 5){
                $level_id = 2;
            }else{
                $level_id = 1;
            }
        }
        self::where('id', $user_id)
            ->inc('spending', $goods_num)
            ->update([
                'level_id'=>$level_id
        ]);
        if(!empty($parent_ids)){
            $str = str_replace('|', ',', substr_replace(substr_replace($parent_ids, '', 0, 1), '', -1, 1));
            self::whereIn('id', $str)->inc('performance', $goods_num)->update();
        }
        return true;
    }

    public static function grantDirectorAllowances($goods_num)
    {
        //发放董事补贴
        $director_list = self::where('level_id', 6)->select();
        $director_amount = 1000;
        $total_director_amount = bcmul($director_amount, $goods_num);
        $director_type = 'shop_director_allowances';
        foreach ($director_list as $director)
        {
            //induce($user_id, $amount, $alias = 'score', $type = 'shop_pay', $des = '')
            self::induce($director['id'], $total_director_amount, 'score', $director_type);
        }
        return true;
            //honor
    }

    public static function afterTransfer($currentUserId, $toUserId, $amount, $alias, $type){
        $deDes = "【你向ID：" . $toUserId . "的会员进行" . Base::$walletTypeArray[$alias] . "转账】";
        $inDes = "【你收到来自ID：" . $currentUserId . "的会员的" . Base::$walletTypeArray[$alias] . "转账】";

        Db::startTrans();
        try {
            //deduce($userId, $amount, $alias = 'money', $level1 = 0, $level2 = 0, $des = '')
            User::deduce($currentUserId, $amount, $alias, $type, $deDes);
            //induce($userId, $amount, $alias = 'balance', $type = '', $des = '')
            User::induce($toUserId, $amount, $alias, $type, $inDes);

            Db::commit();
        } catch (\Exception $exception) {

            Db::rollback();

            Log::error('afterTransfer:'.json_encode(['message' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()], JSON_UNESCAPED_UNICODE));
            return false;
        }

        return true;
    }

    public static function afterWithdrawals($userId, $totalAmount, $alias, $type, $add){
        Db::startTrans();
        try {
            //deduce($userId, $amount, $alias = 'money', $level1 = 0, $level2 = 0, $des = '')
            User::deduce($userId, $totalAmount, $alias, $type);

            UserWalletApply::create($add);

            Db::commit();
        } catch (\Exception $exception) {

            Db::rollback();

            Log::error('afterWithdrawals:'.json_encode(['message' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()], JSON_UNESCAPED_UNICODE));
            return false;
        }

        return true;
    }

    public static function induce($user_id, $amount, $alias = 'score', $type = 'shop_pay', $des = '')
    {
        //钱包增加逻辑 induce deduce locking unlocking
        $user = self::find($user_id);
        $add = [];
        $add['user_id'] = $user_id;
        $add['amount'] = $amount;
        $add['type'] = $type;
        $add['content'] = Base::$walletLogDesArray[$type] . $des;
        $add['before'] = $user[$alias];
        $add['mode'] = 'inc';

        $update = [];
        $update[$alias] = bcadd($add['before'], $amount);
        $add['after'] = $update[$alias];

        $user->save($update);
        switch ($alias)
        {
            case 'score':{
                UserScoreLog::create($add);
            }
                break;
        }
        if($type == 'admin_recharge'){
            $add['alias'] = $alias;
            UserRechargeLog::create($add);
        }
        return true;
    }

    public static function deduce($user_id, $amount, $alias = 'score', $type = 'benefit_pay', $des = '')
    {
        //钱包减少逻辑 induce deduce locking unlocking
        $user = self::find($user_id);
        $add = [];
        $add['user_id'] = $user_id;
        $add['amount'] = $amount;
        $add['type'] = $type;
        $add['content'] = Base::$walletLogDesArray[$type] . $des;
        $add['before'] = $user[$alias];
        $add['mode'] = 'dec';

        $update = [];
        $update[$alias] = bcsub($add['before'], $amount);
        if($update[$alias] < 0){
//            $update[$alias] = 0;
            return false;
        }
        $add['after'] = $update[$alias];

        $user->save($update);
        switch ($alias)
        {
            case 'score':{
                UserScoreLog::create($add);
            }
                break;
        }
        if($type == 'admin_deduct'){
            $add['alias'] = $alias;
            UserRechargeLog::create($add);
        }
        return true;
    }

    public function userLevel()
    {
        return $this->hasOne(Level::class, 'id', 'level_id')->bind([
            'level_name'=>'name',
        ]);
    }

    public function getLevelNameAttr($value)
    {
        return $value ?? '普通用户';
    }

    public function userVirtualLevel()
    {
        return $this->hasOne(Level::class, 'id', 'virtual_level_id')->bind([
            'virtual_level_name'=>'name',
        ]);
    }

    public function getVirtualLevelNameAttr($value)
    {
        return $value ?? '普通用户';
    }

    public function getValuesAttr($value, $data)
    {
        $array = [];
        $array[] = 'ID：' . $data['id'];
        $array[] = '手机号码：' . $data['phone'];
//        $array[] = '总业绩：' . ($data['mode_one_total'] / 100);
//        $array[] = '个人消费：' . bcdiv_amount($data['spending']);
//        $array[] = '销售业绩：' . bcdiv_amount($data['performance']);
        return $array;
    }






//    public function userModeThreeLevel()
//    {
//        return $this->hasOne(ModeThreeLevel::class, 'id', 'mode_three_level_id')->bind([
//            'mode_three_level_name'=>'name',
//        ]);
//    }
//
//
//
//    public function getModeThreeLevelNameAttr($value)
//    {
//        return $value ?? 'V0';
//    }

    public function getAvatarAttr($value)
    {
//        return $this::$oldImageUrl . $value;
        return $this::getOldUrl() . $value;
    }




    public function getPigCountFormatAttr($value, $data)
    {
        $count = PigOrder::where('user_id', $data['id'])
            ->where('status', 'payed')
            ->count();
        return $count;
    }












    /**
     * 获取团队的所有人
     * @param null $ids
     * @return array
     * @throws
     */
    public function getAllChildren($ids = null)
    {
        $ids    = $ids ?: [];
        $newIds = self::whereIn('pid', $ids)->field([ 'id', 'pid' ])->select()->column('id');
        if (count($newIds) > 0) {
            $childId = $this->getAllChildren($newIds);
            return array_merge($newIds, $childId);
        }
        return $newIds;
    }

    /**
     * 获取直推的所有人
     * @param null $ids
     * @return array
     * @throws
     */
    public function getDirect($ids = null)
    {
        $newIds = self::whereIn('pid', $ids)->field([ 'id', 'pid' ])->select()->column('id');
        return $newIds;
    }

    //往上更新业绩 不含复购买
    public function updateAchievement($userId, $amount)
    {
        if($userId == 0){
            return true;
        }else{
            \app\api\model\User::where('id', $userId)
                ->inc('performance', (float)$amount)
                ->inc('day_performance', (float)$amount)
                ->inc('that_performance', (float)$amount)
//                'day_performance'=>(float)$amount,
                ->update();
//            \app\api\model\User::where('id', $userId)->inc('day_performance',(float)$amount)->update();
//            \app\api\model\User::where('id', $userId)->inc('day_performance',(float)$amount)->update();
//            \app\api\model\User::where('id', $userId)->inc('performance',(float)$amount)->update();
//            Db::name('user')->where('id', $userId)->inc('day_performance',(float)$amount)->update();
//            Db::name('user')->where('id', $userId)->inc('performance',(float)$amount)->update();
            $user = \app\api\model\User::field('pid')->find($userId);
            $this->updateAchievement($user['pid'], $amount);
        }
    }

    //往上更新业绩 含复购买
    public function updateAchievementFt($userId, $amount)
    {
        if($userId == 0){
            return true;
        }else{
            \app\api\model\User::where('id', $userId)
                ->inc('performance', (float)$amount)
                ->inc('day_performance', (float)$amount)
                ->inc('that_performance', (float)$amount)
                ->inc('ft_performance', (float)$amount)
                ->update();
            $user = \app\api\model\User::field('pid')->find($userId);
            $this->updateAchievementFt($user['pid'], $amount);
        }
    }

    public function getAgent($pid, $data = array()){
        $user =  Db::name('user')->where('id='.$pid)->field('id,pid')->find();
//        $user =  Db::name('user')->where('id='.$pid)->field('id,pid')->find();
        if($user){
            $data[] = $user['id'];
            return $this->getAgent($user['pid'],$data);
        }
        return count($data) > 0 ? $data : 0;
    }

    //往上更新年猪业绩 不含复购买
    public function updatePigAchievement($userId, $amount)
    {
        if($userId == 0){
            return true;
        }else{
            \app\api\model\User::where('id', $userId)
                ->inc('team_pig_performance', $amount)
                ->update();
            $user = \app\api\model\User::field('pid')->find($userId);
            $this->updatePigAchievement($user['pid'], $amount);
        }
    }

    public static function uniqueInviteCode()
    {
        $invite_code = Str::random(5, 2, '0123456789');
        //判断信息
        if (User::where("invite_code", $invite_code)->find()) {
            //重新获取
            return self::uniqueInviteCode();
        }
        //返回邀请码
        return $invite_code;
    }

    public static function afterOpenMember($user_id, $merchant_id, $amount, $alias, $type)
    {
        //激活会员
        $user_info = self::find($user_id);
        $virtual_level_id = $user_info['virtual_level_id'] > 0 ? $user_info['virtual_level_id'] : 1;

        $parent_id = $user_info['pid'];
        $direct_count = self::where('pid', $user_info['pid'])->where('level_id', '>', 0)->count();
        $direct_rate = (self::$direct_rate)['odd'];
        if(($direct_count + 1) % 2 == 0)
        {
            $direct_rate = (self::$direct_rate)['even'];
        }
        $direct_amount = bcmul($amount, $direct_rate);

        $parent_pid = self::where('id', $parent_id)->value('pid');

        $team_direct_ids = [];
        $team_indirect_ids = [];
        if($parent_pid != 0)
        {
            if($parent_parent_parent_ids = self::where('id', $parent_pid)->value('parent_ids'))
            {
                $str = substr_replace(substr_replace($parent_parent_parent_ids, '', 0, 1), '', -1, 1);
                $ids_array = explode('|', $str);
                $team_direct_ids = array_merge(array($parent_pid), $ids_array);
                $team_indirect_ids = $ids_array;
            }else{
                $team_direct_ids[] = $parent_pid;
            }
        }
//        return [$team_direct_ids, $team_indirect_ids];

        Db::startTrans();
        try {
            //deduce($user_id, $amount, $alias = 'money', $type = 'benefit_pay', $des = '')
            $isDone = self::deduce($user_id, $amount, $alias, $type);
            if($isDone === true){
                MemberOrders::create([
                    'order_sn'=>'MEMBER-' . date('YmdHis') . strtoupper(Str::random()),
                    'user_id'=>$user_id,
                    'merchant_id'=>$merchant_id,
                    'total_amount'=>$amount,
                    'status'=>'payed',
                    'pay_type'=>$alias,
                    'pay_time'=>date('Y-m-d H:i:s'),
                    'update_time'=>date('Y-m-d H:i:s'),
                ]);
                self::where('id', $user_id)->update([
                    'level_id'=>1,
                    'virtual_level_id'=>$virtual_level_id,
                ]);

                //父级直推奖
                //induce($user_id, $amount, $alias = 'score', $type = 'shop_pay', $des = '')
                self::induce($parent_id, $direct_amount, $alias, 'member_open_direct');
                $team_direct_amount = $direct_amount;
                foreach ($team_direct_ids as $team_direct_id)
                {
                    $team_direct_amount = bcmul($team_direct_amount, self::$team_rate);
                    if($team_direct_amount < 1000)
                    {
                        break;
                    }else{
                        self::induce($team_direct_id, $team_direct_amount, $alias, 'member_open_team_direct');
                    }
                }

                if($parent_pid != 0)
                {
                    //父级的父级间推奖
                    $indirect_amount = bcmul($amount, self::$indirect_rate);
                    //induce($user_id, $amount, $alias = 'score', $type = 'shop_pay', $des = '')
                    self::induce($parent_pid, $indirect_amount, $alias, 'member_open_indirect');
                    $team_indirect_amount = $indirect_amount;
                    foreach ($team_indirect_ids as $team_indirect_id)
                    {
                        $team_indirect_amount = bcmul($team_indirect_amount, self::$team_rate);
                        if($team_indirect_amount < 1000)
                        {
                            break;
                        }else{
                            self::induce($team_indirect_id, $team_indirect_amount, $alias, 'member_open_team_indirect');
                        }
                    }
                }

                //induce($id, $amount, $alias = 'score', $type = 'shop_pay', $des = '')
                Merchant::induce($merchant_id, self::$merchant_one_member_amount, 'score', 'member_open_grant_merchant', '【ID：' . $user_id . '】');
            }else{
                Db::rollback();
                return false;
            }

            Db::commit();
        } catch (\Exception $exception) {

            Db::rollback();

            Log::error('afterOpenMember:'.json_encode(['message' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()], JSON_UNESCAPED_UNICODE));
            return false;
        }

        return true;
    }

    public static function afterOpenMerchant($user_id, $merchant_id, $amount, $alias, $type, $add)
    {
        //入驻商家
        $user_info = self::find($user_id);

        $parent_id = $user_info['pid'];
        $direct_amount = bcmul($amount, self::$merchant_direct_rate);
        $parent_pid = self::where('id', $parent_id)->value('pid');

        Db::startTrans();
        try {
            //deduce($user_id, $amount, $alias = 'money', $type = 'benefit_pay', $des = '')
            $isDone = self::deduce($user_id, $amount, $alias, $type);
            if($isDone === true){
                Merchant::create($add);
                MemberOrders::create([
                    'order_sn'=>'MERCHANT-' . date('YmdHis') . strtoupper(Str::random()),
                    'user_id'=>$user_id,
                    'merchant_id'=>$merchant_id,
                    'total_amount'=>$amount,
                    'type'=>'merchant',
                    'status'=>'payed',
                    'pay_type'=>$alias,
                    'pay_time'=>date('Y-m-d H:i:s'),
                    'update_time'=>date('Y-m-d H:i:s'),
                ]);
                self::where('id', $user_id)->update([
                    'merchant_status'=>'on',
                ]);

                //父级直推奖
                //induce($user_id, $amount, $alias = 'score', $type = 'shop_pay', $des = '')
                self::induce($parent_id, $direct_amount, $alias, 'merchant_open_direct');
                if($parent_pid != 0)
                {
                    //父级的父级间推奖
                    $indirect_amount = bcmul($amount, self::$merchant_indirect_rate);
                    //induce($user_id, $amount, $alias = 'score', $type = 'shop_pay', $des = '')
                    self::induce($parent_pid, $indirect_amount, $alias, 'merchant_open_indirect');
                }
            }else{
                Db::rollback();
                return false;
            }

            Db::commit();
        } catch (\Exception $exception) {

            Db::rollback();

            Log::error('afterOpenMerchant:'.json_encode(['message' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()], JSON_UNESCAPED_UNICODE));
            return false;
        }

        return true;
    }
}